#include "r_socket_ipv4_udp_server.h"

#include "utilities/string_operator.h"

namespace eniac
{

r_socket_proxy_ret_t r_socket_ipv4_udp_server::set_socket_property(const r_socket::ptr socket, r_socket_property_type type, void* property, size_t property_size)
{
    if (nullptr == socket.get())
    {
        return r_socket_proxy_ret_t::NULL_PTR;
    }

    if (type == r_socket_property_type::SOCKET_PROPERTY_OWN_ADDRESS)
    {
        return set_socket_own_address(socket, property, property_size);
    }

    if (type != r_socket_property_type::SOCKET_PROPERTY_OWN_PORT_NUMBER)
    {
        return set_socket_own_port(socket, property, property_size);
    }

    return r_socket_proxy_ret_t::INVALID_PROPERTY_TYPE_FOR_THE_SOCKET;
}

r_socket_proxy_ret_t r_socket_ipv4_udp_server::set_socket_own_address(const r_socket::ptr socket, void* property, size_t property_size)
{
    if ( property_size < strlen("0.0.0.0") ||
         property_size > strlen("000.000.000.000") )
    {
        return r_socket_proxy_ret_t::INVALID_PROPERTY_LENGTH;
    }

    std::string ip_str = reinterpret_cast<char*>(property);

    if (false == is_valid_ipv4_ip(ip_str) )
    {
        return r_socket_proxy_ret_t::INVALID_PROPERTY_VALUE;
    }

    socket->m_own_address = ip_str;

    return r_socket_proxy_ret_t::OK;
}

r_socket_proxy_ret_t r_socket_ipv4_udp_server::set_socket_own_port(const r_socket::ptr socket, void* property, size_t property_size)
{
    if (property_size != sizeof(socket->m_own_port))
    {
        return r_socket_proxy_ret_t::INVALID_PROPERTY_LENGTH;
    }

    if (INVALID_SOCKET_PORT == *reinterpret_cast<uint16_t*>(property))
    {
        return r_socket_proxy_ret_t::INVALID_PROPERTY_VALUE;
    }
    socket->m_own_port = *reinterpret_cast<uint16_t*>(property);

    return r_socket_proxy_ret_t::OK;
}

}